package com.sugon.service.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.sugon.dao.DevAmRulesDao;
import com.sugon.dao.DevMainBaseAmDao;
import com.sugon.dao.SysUserRoleDao;
import com.sugon.entity.*;
import com.sugon.entity.dto.MaintenanceRuleImportParam;
import com.sugon.modules.base.model.vo.ProcessProgressConst;
import com.sugon.modules.utils.DateUtil;
import com.sugon.service.*;
import com.sugon.utils.*;
import org.apache.shiro.util.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 自主维护规程管理Service实现类
 *
 * @author YuXD
 * @date 2023-01-23
 */
@Service("devMaintenanceRulesService")
public class DevAmRulesServiceImpl implements DevAmRulesService {

    @Autowired
    private DevAmRulesDao devAmRulesDao;
    @Autowired
    private SysMsgService sysMsgService;
    @Autowired
    private SysUserRoleDao sysUserRoleDao;
    @Autowired
    private SysDeptService deptService;
    @Resource
    private DeviceInfoService deviceService;
    @Resource
    private DevMainBaseAmDao devMainBaseAmDao;
    @Resource
    private DevAmRulesOptionService devAmRulesOptionService;

    /**
     * @param id 主键
     * @return
     */
    @Override
    public DevAmRulesEntity queryObject(String id) {
        return devAmRulesDao.queryObject(id);
    }

    @Override
    public boolean checkExists(String devId, String planVersion) {
        Map<String, Object> param = new HashMap<>(2);
        param.put("devId", devId);
        param.put("planVersion", planVersion);
        return queryTotal(param) > 0;
    }

    /**
     * @param map 参数
     * @return
     */
    @Override
    public List<DevAmRulesEntity> queryList(Map<String, Object> map) {
        List<String> list = sysUserRoleDao.queryRoleIdList(ShiroUtils.getUserId());
        for (int i = 0; i < list.size(); i++) {
            String code = list.get(i);
            if (code.equals(Constant.ZZC_PESQ)) {//pe授权工程师
                map.put("checkStatus", 1);
            }
        }
        return devAmRulesDao.queryList(map);
    }

    /**
     * @param map 参数
     * @return
     */
    @Override
    public int queryTotal(Map<String, Object> map) {
        List<String> list = sysUserRoleDao.queryRoleIdList(ShiroUtils.getUserId());
        for (int i = 0; i < list.size(); i++) {
            if (Constant.ZZC_PESQ.equals(list.get(i))) {//pe授权工程师
                map.put("checkStatus", 1);
            }
        }
        return devAmRulesDao.queryTotal(map);
    }

    /**
     * @param devMaintenPlan 实体
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int save(DevAmRulesEntity devMaintenPlan) {
        devMaintenPlan.setId(RandomUtil.randomString(32));
        devMaintenPlan.setDelFlag(Constant.IS_NOT_DEL_INT);
        devMaintenPlan.setOrgUserId(ShiroUtils.getUserId());
        devMaintenPlan.setPlanVersion(generateUniqueCode(devMaintenPlan));
        return devAmRulesDao.save(devMaintenPlan);
    }

    /**
     * 生成规程版本
     *
     * @param data
     * @return
     */
    @Override
    public String generateUniqueCode(Object data) {
        DevAmRulesEntity devPmRule = (DevAmRulesEntity) data;
        String workshop = ShiroUtils.getWorkshop();
        Assert.notNull(workshop, "只有处于某部门下的用户执行该操作！");
        // 设置备件需求计划编码
        SysDeptEntity deptEntity = deptService.queryObject(workshop);
        Assert.notNull(deptEntity, "非法所属部门编码！");
        String planVersionPrefix = deptEntity.getDcode() + "-" + DateUtil.getYearAndMonth(null) + "-";
        String lastDCode = devAmRulesDao.getLastDCode(devPmRule.getDevId(), planVersionPrefix);
        return com.sugon.modules.utils.StrUtil.increase(lastDCode, planVersionPrefix, 2, 1);
    }

    /**
     * @param devMaintenPlan 实体
     * @return
     */
    @Override
    public int update(DevAmRulesEntity devMaintenPlan) {
        int rows = devAmRulesDao.update(devMaintenPlan);
        if (rows > 0) {
            SysMsgEntity msgEntity = new SysMsgEntity();
            String Id = devMaintenPlan.getId();
            msgEntity.setDataId(Id);
            msgEntity.setDataUrl("../device/devMaintenanceRules.html?Id=" + Id);
            sysMsgService.addApproveItem(ProcessInfoEnum.DEV_WHGC, msgEntity, 0);
        }
        return rows;
    }

    @Override
    public Map<String, Object> prepareExportData(Map<String, Object> params) {
        Map<String, Object> resultMap = MapUtil.newHashMap();
        // 指导处有效的自主维护规程
        params.put("isValid", 1);
        resultMap.put("list", devAmRulesDao.queryItemList(params));
        return resultMap;
    }

    /**
     * @param id
     * @return
     */
    @Override
    public int delete(String id) {
        return devAmRulesDao.delete(id);
    }

    /**
     * @param ids
     * @return
     */
    @Override
    public int deleteBatch(String[] ids) {
        return devAmRulesDao.deleteBatch(ids);
    }

    @Override
    public List<DevAmRulesEntity> list(String devId, Integer progress, Integer isValid) {
        Map<String, Object> param = MapUtil.newHashMap();
        param.put("devId", devId);
        if (progress != null) {
            param.put("progress", progress);
        }
        if (isValid != null) {
            param.put("isValid", isValid);
        }
        return queryList(param);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String imports2(MultipartFile file) {
        String importResult = "共导入设备维护规程数：{}，维护项条数：{}";
        // 上传Excel内容不得为空
        if (file == null || file.isEmpty()) {
            throw new RRException("上传文件不能为空");
        }
        // 导入规程数
        int rows = 0;
        // 导入维护项条数
        int itemRows = 0;
        ImportParams importParams = new ImportParams();
        importParams.setNeedVerify(true);
        // 需要读取所有sheet
        importParams.setSheetNum(0);
        List<MaintenanceRuleImportParam> ruleParams = null;
        try {
            // 读取内容
            ruleParams = ExcelImportUtil.importExcel(file.getInputStream(), MaintenanceRuleImportParam.class, importParams);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 如果无法读取内容，则直接返回
        if (CollectionUtil.isEmpty(ruleParams)) {
            return StrUtil.format(importResult, rows, itemRows);
        }
        Map<String, List<MaintenanceRuleImportParam>> devRuleMap = ruleParams.stream().collect(Collectors.groupingBy(MaintenanceRuleImportParam::getDevCode));
        // 获取规程版本号
        Set<Map.Entry<String, List<MaintenanceRuleImportParam>>> entrySet = devRuleMap.entrySet();
        String devCode;
        List<MaintenanceRuleImportParam> maintenanceItemList;
        outer:
        for (Map.Entry<String, List<MaintenanceRuleImportParam>> entry : entrySet) {
            devCode = StrUtil.trim(entry.getKey());
            // 根据设备编码获取设备信息
            DeviceInfoEntity device = deviceService.getInfoByDevCode(devCode);
            if (device == null) {
                continue;
            }
            // 保存规程项
            maintenanceItemList = entry.getValue();
            // 去除重复元素：防止客户在拍计划时同一个维护项排了多次
            maintenanceItemList = maintenanceItemList.stream().filter(DeduplicationUtil.distinctByKey(MaintenanceRuleImportParam::getCode)).collect(Collectors.toList());
            // 获取设备维护项列表。如果不存在，则跳过
            List<DevMainBaseAmEntity> devAmItemList = devMainBaseAmDao.listByCodeList(maintenanceItemList.stream().map(MaintenanceRuleImportParam::getCode).collect(Collectors.toList()));
            if (CollectionUtil.isEmpty(devAmItemList)) {
                continue;
            }

            // 校验校验设备的新老规程 维护项是否发生变化。如果未发生变化，那么不做任何处理
            List<DevAmRulesEntity> existedAmRuleList = list(device.getId(), ProcessProgressConst.PASSED, 1);
            if (CollectionUtil.isNotEmpty(existedAmRuleList)) {
                for (DevAmRulesEntity existedPmRule : existedAmRuleList) {
                    List<DevAmRulesOptionEntity> oldDevRuleOptionList = devAmRulesOptionService.getByPlanId(existedPmRule.getId());
                    if (CollectionUtil.isEmpty(oldDevRuleOptionList)) {
                        continue;
                    }
                    // 校验新老规程是否发生变化
                    if (CollectionUtil.isEqualList(devAmItemList.stream().map(DevMainBaseAmEntity::getId).sorted(String::compareTo).collect(Collectors.toList()), oldDevRuleOptionList.stream().map(DevAmRulesOptionEntity::getMainBaseId).sorted(String::compareTo).collect(Collectors.toList()))) {
                        continue outer;
                    }
                }
            }

            // 设置基础信息
            DevAmRulesEntity devAmRule = new DevAmRulesEntity();
            devAmRule.setRuleName(device.getDevName() + "_维护规程");
            devAmRule.setDevId(device.getId());
            devAmRule.setProgress(ProcessProgressConst.DEPT_APPROVING);
            devAmRule.setIsValid(1);
            devAmRule.setPlanCon("无");
            rows += save(devAmRule);
            // 保存设备维护规程项
            for (DevMainBaseAmEntity devAmItem : devAmItemList) {
                DevAmRulesOptionEntity devPlanOption = new DevAmRulesOptionEntity(devAmRule.getId(), devAmItem.getId());
                itemRows += devAmRulesOptionService.save(devPlanOption);
            }
        }
        return StrUtil.format(importResult, rows, itemRows);
    }

}
